package com.frain.springcloud.hystrix.original;

import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;

public class HystrixOriginalCommand extends HystrixCommand<String> {

    private String path;

    public HystrixOriginalCommand(String path) {
        // java代码配置， 只针对这个命令
        super(Setter
                // 必填项。指定命令分组名，主要意义是用于统计
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey("biz-provider-01Group"))
                // 依赖名称（如果是服务调用，这里就写具体的接口名， 如果是自定义的操作，就自己命令），默认是command实现类的类名。 熔断配置就是根据这个名称
                .andCommandKey(HystrixCommandKey.Factory.asKey("timeThreeFinishCommandKey"))
                // 线程池命名，默认是HystrixCommandGroupKey的名称。 线程池配置就是根据这个名称
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("biz-provider-01ThreadPool"))
                // command 熔断相关参数配置
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        // 配置隔离方式：默认采用线程池隔离。还有一种信号量隔离方式,
                        // .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
                        // 超时时间500毫秒
                        .withExecutionTimeoutInMilliseconds(4500)
                // 信号量隔离的模式下，最大的请求数。和线程池大小的意义一样
                // .withExecutionIsolationSemaphoreMaxConcurrentRequests(2)
                // 熔断时间（熔断开启后，各5秒后进入半开启状态，试探是否恢复正常）
                // .withCircuitBreakerSleepWindowInMilliseconds(5000)
                )
                // 设置线程池参数
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                        // 线程池大小
                        .withCoreSize(1)));
        this.path = path;
    }

    @Override
    protected String run() throws Exception {
        System.out.println("###command#######" + Thread.currentThread().toString());

        String result = new RestTemplate().getForEntity(path, String.class).getBody();

        System.out.println(
                "###command结束#######" + Thread.currentThread().toString() + ">><>>>执行结果:" + new String(result));
        return new String(result);
    }

    @Override
    protected String getFallback() {

        System.out.println("降级了。。。" + Thread.currentThread().getName());

        return "降级了";
    }

}
